package com.aca.market.service.impl;

import com.aca.market.entity.ShiroFilter;
import com.aca.market.mapper.ShiroFilterMapper;
import com.aca.market.service.IShiroFilterService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author aca
 * @since 2020-11-13
 */
@Service(value = "shiroFilterService")
@Slf4j
public class ShiroFilterServiceImpl extends ServiceImpl<ShiroFilterMapper, ShiroFilter>
        implements IShiroFilterService, ApplicationContextAware {

    private static ApplicationContext context;

    @Autowired
    ShiroFilterMapper shiroFilterMapper;

    @Autowired
    ShiroFilterFactoryBean factory;


    @Override
    public void reloadFilterChains() {
//        ShiroFilterFactory factory = (ShiroFilterFactory) context.getBean("shiroFilterFactoryBean");
        synchronized (factory) {   //强制同步，控制线程安全
            AbstractShiroFilter shiroFilter = null;

            try {
                shiroFilter = (AbstractShiroFilter) factory.getObject();

                PathMatchingFilterChainResolver resolver = (PathMatchingFilterChainResolver) shiroFilter
                        .getFilterChainResolver();
                // 过滤管理器
                DefaultFilterChainManager manager = (DefaultFilterChainManager) resolver.getFilterChainManager();
                // 清除权限配置
                manager.getFilterChains().clear();
                factory.getFilterChainDefinitionMap().clear();
                // 重新设置权限
                // /传入配置中的filterchains
                factory.setFilterChainDefinitionMap(initShiroFilter());

                Map<String, String> chains = factory.getFilterChainDefinitionMap();
                //重新生成过滤链
                if (!CollectionUtils.isEmpty(chains)) {
                    chains.forEach((url, definitionChains) -> {
                        manager.createChain(url, definitionChains.trim().replace(" ", ""));
                    });
                }
                log.info("FILTER===============update");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
//        System.out.println("==================更新之后的");
//        factory.getFilterChainDefinitionMap().forEach((k,v)-> System.out.println("k:"+k+" ,v:"+v));
    }



    @Override
    public Map<String,String> initShiroFilter(){
        Map<String,String> filterMap = null;
        List<ShiroFilter> filterList = shiroFilterMapper.selectList(new QueryWrapper<ShiroFilter>().select("name", "perms"));
        if (!filterList.isEmpty()){
            filterMap = new HashMap<>();
            for (ShiroFilter filter : filterList) {
                log.info("================FILTER: " + filter.getName()+" , "+filter.getPerms());
                filterMap.put(filter.getName(),filter.getPerms());
            }
        }
        return filterMap;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
}
